package org.compiere.model;

import java.io.File;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;

import org.compiere.apps.IProcessParameter;
import org.compiere.apps.ProcessCtl;
import org.compiere.apps.ProcessParameterPanel;
import org.compiere.process.DocAction;
import org.compiere.process.ProcessInfo;
import org.compiere.util.ASyncProcess;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;

public class MTRMApplication extends X_TRM_Application implements DocAction, ASyncProcess {

	/**
	 * 
	 */
	private static final long serialVersionUID = -9142643033197058744L;

	public MTRMApplication(Properties ctx, int TRS_Application_ID,
			String trxName) {
		super(ctx, TRS_Application_ID, trxName);
	}
	
	/**
	 *  Load Constructor
	 *  @param ctx context
	 *  @param rs result set record
	 *	@param trxName transaction
	 */
	public MTRMApplication(Properties ctx, ResultSet rs, String trxName)
	{
		super(ctx, rs, trxName);
	}	//	MInvoice

	@Override
	protected boolean beforeDelete (){
		
		//can remove order only, mans of dkf (depid = 2000021)
		// or boss of dep of initiator
		
		int userID = Env.getAD_User_ID(Env.getCtx());
		int c_bpartner_id = DB.getSQLValue(null, "select c_bpartner_id from adempiere.ad_user where ad_user_id = " + userID);
		
		int depID = DB.getSQLValue(null, "select hr_department_id		\n" + 
				"from adempiere.hr_employee 		\n" +
				"where c_bpartner_id = "+ c_bpartner_id +"		\n" +
				"group by 1 " );
		
		
		int BPInitiatorID = DB.getSQLValue(null, "select c_bpartner_id from adempiere.ad_user where ad_user_id = " + getInitiator_ID());
		int jobcategoryID = DB.getSQLValue(null, "select j.C_JobCategory_ID		\n" + 
				"from adempiere.hr_employee e		\n" +
				"inner join adempiere.hr_job j on j.hr_job_id = e.hr_job_id		\n" +
				"where e.c_bpartner_id = "+ BPInitiatorID +"		\n" +
				"group by 1 " );		
		
		
		if(depID != 2000021 || jobcategoryID != 1000005){
			log.saveError("Error", Msg.getMsg(getCtx(), "Отсутствуют полномочия на удаление Финансовой Заявки"));
			return false;
		}

		
		return true;
		
	}
	
	protected boolean beforeSave(boolean newRecord)
	{
		
		int year = getDateAcct().getYear()+1900;
		int month = getDateAcct().getMonth();
		
		String sql = 
			"select p.bpm_project_id from	\n"	+ 
			"adempiere.bpm_project p 	\n"	+
			"inner join adempiere.bpm_versionbudget b on b.bpm_versionbudget_id = p.bpm_versionbudget_id	\n"	+ 
			"inner join adempiere.c_year c on c.c_year_id = b.c_year_id	\n"	+
			"where c.fiscalyear = '"+year+"'	\n"	+
			"and iswork = 'Y'";
		
		int bpm_project_id = DB.getSQLValue(null, sql);
		if(bpm_project_id < 0){
			log.saveError("Error", Msg.getMsg(getCtx(), "Отсутсвует бюджетная заявка на этот год"));
			return false;
		}
		
		int userID = getInitiator_ID();
		int c_bpartner_id = DB.getSQLValue(null, "select c_bpartner_id from adempiere.ad_user where ad_user_id = " + userID);
		

		int depID = DB.getSQLValue(null, "select hr_department_id		\n" + 
				"from adempiere.hr_employee 		\n" +
				"where c_bpartner_id = "+ c_bpartner_id +"		\n" +
				"group by 1 " );
		
		sql = 
		"select bc.bpm_budgetcall_id, ba.hr_department_id	\n"	+
		"from adempiere.bpm_budgetcall bc\n"	+ 
		"inner join adempiere.bpm_abp ba on ba.bpm_abp_id = bc.bpm_abp_id\n"	+
		"where bpm_project_id = "+ bpm_project_id;
		
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		List<Integer> list = new ArrayList<Integer>();
		try
		{
			pstmt = DB.prepareStatement(sql, null);
			rs = pstmt.executeQuery();
			
			while(rs.next())
				if(depID == rs.getInt(2))
					list.add(rs.getInt(1));
				
		}
		catch(Exception e){}
		
		if(list.size() == 0){
			log.saveError("Error", Msg.getMsg(getCtx(), "Сумма не предусмотрена в бюджетной заявке."));
			return false;
		}
		
		double summ = .0;
		
		for(Integer i: list){
			 
			sql = "select coalesce(sum(bl.amount),0) from adempiere.bpm_budgetcallline	bl\n"	+ 
					"	inner join adempiere.c_period p on p.c_period_id = bl.c_period_id \n"	+
					"	where bl.bpm_budgetcall_id = "+i+" and bl.c_charge_id = " +getC_Charge_ID() +"\n"+
					"	and bl.record_id = "+get_ValueAsInt("BPM_ServicesWork_ID")+
					"	and '" + getDateAcct() + "' between p.startdate and p.enddate ";
					
			double s = DB.getSQLValue(null,sql);
			if(s != -1)
				summ += s; 
		}
		
//		sql = "select coalesce(sum(paymentsum),0) from adempiere.cms_payment \n"	+
//				"where extract(month from dateacct) = "+month+" and extract(year from dateacct) = "+year;
				
//		double contractpay = DB.getSQLValue(null,sql);
		double contractpay = getApplAmount().doubleValue();
		
		if(contractpay > summ){
			
//			log.log(Level.WARNING, "Сумма контракта меньше суммы статей затрат бюджетной заявки");
			log.saveError("Error", Msg.getMsg(getCtx(), "Сумма заявки превышает сумму по статье затрат бюджетной заявки"));
			return false;
		}
				
		
		return true;
	}

	
	/**
	 * 	After Save
	 *	@param newRecord new
	 *	@param success success
	 *	@return success
	 */
	protected boolean afterSave (boolean newRecord, boolean success)
	{
		
		int ad_process_id = getProcess();
		
		if(ad_process_id == -1) return true;
		
		ProcessInfo pi = new ProcessInfo("Inform Department Header", ad_process_id, this.get_Table_ID(), this.get_ID());
		pi.setAD_Client_ID(this.getAD_Client_ID());
		pi.setAD_User_ID(this.getInitiator_ID());
		
		ProcessParameterPanel pu = new ProcessParameterPanel(0, pi);
		ProcessCtl.process(this, 0, (IProcessParameter) pu, pi, null);

		return success;
	}	//	afterSave
	
	private int getProcess()
	{
		String sql = "select ad_process_id from ad_process where lower(name) like '%trm_informheader%'";
		
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		int ad_process_id = 0;//DB.getSQLValue(get_TrxName(), sql);
		
		try
		{
			pstmt = DB.prepareStatement(sql, null);
			rs = pstmt.executeQuery();
			
			if(rs.next())
				ad_process_id = rs.getInt(1);
		}
		catch(Exception e){}
		
		return ad_process_id;
	}
	
	@Override
	public void setDocStatus(String newStatus) {
	}

	@Override
	public String getDocStatus() {
		return null;
	}

	@Override
	public boolean processIt(String action) throws Exception {
		return false;
	}

	@Override
	public boolean unlockIt() {
		return false;
	}

	@Override
	public boolean invalidateIt() {
		return false;
	}

	@Override
	public String prepareIt() {
		return null;
	}

	@Override
	public boolean approveIt() {
		return false;
	}

	@Override
	public boolean rejectIt() {
		return false;
	}

	@Override
	public String completeIt() {
		return null;
	}

	@Override
	public boolean voidIt() {
		return false;
	}

	@Override
	public boolean closeIt() {
		return false;
	}

	@Override
	public boolean reverseCorrectIt() {
		return false;
	}

	@Override
	public boolean reverseAccrualIt() {
		return false;
	}

	@Override
	public boolean reActivateIt() {
		return false;
	}

	@Override
	public String getSummary() {
		return null;
	}

	@Override
	public String getDocumentInfo() {
		return null;
	}

	@Override
	public File createPDF() {
		return null;
	}

	@Override
	public String getProcessMsg() {
		return null;
	}

	@Override
	public int getDoc_User_ID() {
		return 0;
	}

	@Override
	public int getC_Currency_ID() {
		return 0;
	}

	@Override
	public BigDecimal getApprovalAmt() {
		return null;
	}

	@Override
	public String getDocAction() {
		return null;
	}

	@Override
	public void lockUI(ProcessInfo pi) {
	}

	@Override
	public void unlockUI(ProcessInfo pi) {
	}

	@Override
	public boolean isUILocked() {
		return false;
	}

	@Override
	public void executeASync(ProcessInfo pi) {
	}
}
